package com.meizi.codegenerate.generate.clien.ui.request;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Modifier;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.utils.StringEscapeUtils;
import com.meizi.codegenerate.constant.AnnotationSettingValueConstant;
import com.meizi.codegenerate.constant.CharacteristicConstant;
import com.meizi.codegenerate.constant.JavaClassNameConstant;
import com.meizi.codegenerate.constant.TableNameConstant;
import com.meizi.codegenerate.entity.ColumnsEntity;
import com.meizi.codegenerate.entity.ProjectPositionEntity;
import com.meizi.codegenerate.entity.TablesEntity;
import com.meizi.codegenerate.enums.ColumnDataTypeEnum;
import com.meizi.codegenerate.enums.IndexesEnum;
import com.meizi.codegenerate.packagegenerate.PackageGenerate;
import com.meizi.codegenerate.utils.AnnotationUtils;
import com.meizi.codegenerate.utils.AttributeConvertUtils;
import com.meizi.codegenerate.utils.ColumnUtils;
import com.meizi.codegenerate.utils.JDBCUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author pc
 * @date 2023/4/28 - 18:08 - 星期五
 * @project lambda
 * @package com.meizi.codegenerate.generate.clien.ui.request
 * @by GGbomd猪猪侠
 */
@Slf4j
public class RequestGenerate {

    /**
     * 创建 requester 请求实体
     * @throws IOException
     */
    public static void createRequester () throws IOException {

        // 在相应的路径下创建对应的文件
        ProjectPositionEntity projectPosition = PackageGenerate.getProjectPosition();
        String requesterUrl = PackageGenerate.obtainRequesterUrl(projectPosition);

        // 获取要生成对应的表名
        List<String> tableNameList = TableNameConstant.getTableNameList();
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        for (String tableName : tableNameList) {
            clearMap(map);

            // 获取数据表的字段名字类型等信息
            List<ColumnsEntity> columnsEntities = JDBCUtils.queryColumns(tableName);
            HashMap<String, String> hashMap = ColumnUtils.columnTypeToImport
                    (ColumnUtils.mapColumnDateType(columnsEntities));
            log.info("import导入 hashMap = {}", hashMap);

            // 获取对数据表得备注信息
            TablesEntity tablesComment = JDBCUtils.queryTablesComment(tableName);
            // 获取对应数据表字段备注信息
            List<ColumnsEntity> columnsCommentList = JDBCUtils.queryColumnsComment(tableName);

            //获取requesterBody java类名
            String className = AttributeConvertUtils.tableNameToJava
                    (tableName, TableNameConstant.TABLE_PREFIX, true)
                    + JavaClassNameConstant.REQUEST_BODY;
            // 获取完成的文件路径创建文件
            String fullPath = requesterUrl + className + TableNameConstant.JAVA;
            log.info("创建ui下requester路径 fullPath = {}", fullPath);

            CompilationUnit compilationUnit = new CompilationUnit();
            // 添加package
            compilationUnit.setPackageDeclaration(PackageGenerate.requesterPackage(projectPosition));
            // 导入import
            for (String key : hashMap.keySet()) {
                String value = hashMap.get(key);
                compilationUnit.addImport(value);
            }

            // 添加类文件
            ClassOrInterfaceDeclaration declaration = compilationUnit.addClass(className).setPublic(true);
            //添加类级别注释
            declaration.setJavadocComment(tablesComment.getTableComment());
            // 添加类级别注解
            declaration.addAnnotation(Data.class);

            map.put(AnnotationSettingValueConstant.CALL_SUPER, AnnotationSettingValueConstant.SET_CALL_SUPER_VALUE);
            declaration.addAnnotation(AnnotationUtils.setAnnotation(EqualsAndHashCode.class, new NodeList<>(),
                    map));
            clearMap(map);

            map.put(AnnotationSettingValueConstant.APIMODEL_VALUE, className);
            map.put(AnnotationSettingValueConstant.APIMODEL_DESCRIPTION, tablesComment.getTableComment());
            declaration.addAnnotation(AnnotationUtils.setAnnotation(ApiModel.class, new NodeList<>(),
                    map));
            clearMap(map);
            //

            // 实例化属性 字段类型
            for (ColumnsEntity columnsEntity : columnsEntities) {
                // 字段备注信息
                for (ColumnsEntity columnComment : columnsCommentList) {
                    if (columnComment.getField().equals(columnsEntity.getField())) {

                        if (columnsEntity.getKey().equals(IndexesEnum.PRI.getValue())) {
                            RequestByIdGenerate.generateById(columnsEntity, tableName, requesterUrl, projectPosition, tablesComment);
                            RequestDeleteByIdGenerate.generateDeleteById(columnsEntity, tableName, requesterUrl, projectPosition, columnsEntities, columnsCommentList, tablesComment);
                        }

                        //StringEscapeUtils.escapeJava(""); 将输入字符串转为unicode编码 / 将unicode字符串转为Utf-8格式的字符串
                        map.put(AnnotationSettingValueConstant.APIMODELPROPERTY_VALUE, StringEscapeUtils.escapeJava(columnComment.getColumnComment()));

                        if (StringUtils.isNotBlank(columnComment.getColumnComment()) &&
                                columnComment.getColumnComment().contains(CharacteristicConstant.TABLELOGIC)) {

                            declaration.addField(
                                    ColumnDataTypeEnum.from(columnsEntity.getType()).getDesc(),
                                    AttributeConvertUtils.columnNameToJava(columnsEntity.getField(), TableNameConstant.COLUMN_PREFIX, false),
                                    Modifier.Keyword.PRIVATE
                            ).setJavadocComment(columnComment.getColumnComment())
                                    .addAnnotation(AnnotationUtils.setAnnotation(ApiModelProperty.class, new NodeList<>(), map))
                                    .addAnnotation(JsonIgnore.class);

                        } else {

                            declaration.addField(
                                    ColumnDataTypeEnum.from(columnsEntity.getType()).getDesc(),
                                    AttributeConvertUtils.columnNameToJava(columnsEntity.getField(), TableNameConstant.COLUMN_PREFIX, false),
                                    Modifier.Keyword.PRIVATE
                            ).setJavadocComment(columnComment.getColumnComment())
                                    .addAnnotation(AnnotationUtils.setAnnotation(ApiModelProperty.class, new NodeList<>(), map));

                        }
                        clearMap(map);
                    }
                }
            }


            System.out.println(compilationUnit.toString());

            /**
             * 把字符串写入文件
             * 参数1：需要写入的文件，如果文件不存在，将自动创建。  参数2：需要写入的内容
             * 参数3：编码格式     参数4：是否为追加模式（ ture: 追加模式，把字符串追加到原内容后面）
             */
            FileUtils.writeStringToFile(new File(fullPath), compilationUnit.toString(), "UTF-8", false);
        }
    }


    private static void clearMap(Map<String, Object> map) {
        map.clear();
    }
}
